module ysyx_22040213_contrl (
	input [6:0] opcode,
	input [2:0] funct3,
	input [6:0] funct7,
	input jumpb,
	input csrrw,
	input csrrs,
	input ecall,
	input mret,

	input divw,
	input divuw,
	input remw,
	input remuw,

	output w_en,
//	output imm_en,
	output pc_en,
//	output jump_en,
	output op_jalr,
	output jumpb_en,
//	output shiftimm_en,
//	output shiftreg_en,
	output lm_en,
	output sm_en,
	output sub_en,
	output word_en,
	output rv64m_en,
	output arith_en,
	output lui_en,
	output srai,
	output [1:0] csr_wen,
	output [4:0] nextpc_en,
	output [3:0] RegisterWritedata_en,
	output [3:0] AluData1_en,
	output [6:0] AluData2_en
);

	assign w_en = (csrrs || csrrw || opcode == 7'b0110111 || opcode == 7'b0011011 || opcode == 7'b0111011 || opcode == 7'b0110011 || opcode == 7'b0000011 || opcode == 7'b0010011 || opcode == 7'b0010111 || opcode == 7'b1100111 || opcode == 7'b1101111 )?1'b1:1'b0;
	assign imm_en = (opcode == 7'b0110111 || opcode == 7'b0000011 || opcode == 7'b0011011 || opcode == 7'b0010111 || opcode == 7'b0010011 || opcode == 7'b0100011)?1'b1:1'b0;
	assign pc_en = ~opcode[6] && ~opcode[5] && opcode[4] && ~opcode[3] && opcode[2] && opcode[1] && opcode[0] || jump_en || op_jalr; 
		//(opcode == 7'b0010111 || opcode == 7'b1101111 || opcode == 7'b1100111)?1'b1:1'b0;//auipc jal jalr
	assign jump_en = opcode[6] && opcode[5] && ~opcode[4] && opcode[3] && opcode[2] && opcode[1] && opcode[0]; 
		//(opcode == 7'b1101111 )?1'b1:1'b0; //jal
	assign op_jalr =  opcode[6] && opcode[5] && ~opcode[4] && ~opcode[3] && opcode[2] && opcode[1] && opcode[0]; 
		//(opcode == 7'b1100111)?1'b1:1'b0; //jalr
	assign sm_en = (opcode == 7'b0100011)?1'b1:1'b0;
	assign lm_en = (opcode == 7'b0000011)?1'b1:1'b0;
	assign shiftimm_en = (opcode == 7'b0010011 || opcode == 7'b0011011)?((funct3 == 3'b101 || funct3 == 3'b001)?1'b1:1'b0):1'b0;
//	assign shiftreg_en = (opcode == 7'b0111011)?1'b1:1'b0;
	assign jumpb_en = (opcode == 7'b1100011)?1'b1:1'b0;
	assign sub_en = ((opcode == 7'b0111011 || opcode == 7'b0110011) && funct7 == 7'b0100000)?1'b1:1'b0;
	assign word_en = (opcode == 7'b0111011 || opcode == 7'b0011011)?1'b1:1'b0;
	assign rv64m_en = ((opcode == 7'b0110011 || opcode == 7'b0111011) && funct7 == 7'b0000001)?1'b1:1'b0;
	assign arith_en = (opcode == 7'b0011011 && funct7 == 7'b0100000)?1'b1:1'b0;
	assign lui_en = (opcode == 7'b0110111)?1'b1:1'b0;
	
	wire jump_en;
	wire shiftimm_en;
	wire imm_en;
	
	wire sraw  = sub_en && ~arith_en &&  funct3[2] && ~funct3[1] &&  funct3[0];
//	wire sraiw = arith_en &&  funct3[2] && ~funct3[1] &&  funct3[0];
	wire srliw = word_en &&  funct3[2] && ~funct3[1] &&  funct3[0] && ~arith_en && ~sub_en;
	assign srai = (opcode == 7'b0010011) && (funct3 == 3'b101) && (funct7[6:1] == 6'b010000);	

	assign nextpc_en[4] = mret;
	assign nextpc_en[3] = ecall;
	assign nextpc_en[2] = jump_en;
	assign nextpc_en[1] = jumpb;
	assign nextpc_en[0] = op_jalr;

	assign RegisterWritedata_en[3] = csrrw || csrrs; //register write t
	assign RegisterWritedata_en[2] = w_en && lm_en;
	assign RegisterWritedata_en[1] = op_jalr || jump_en;
	assign RegisterWritedata_en[0] = ~(w_en && lm_en) & ~(op_jalr || jump_en);

	assign AluData1_en[3] = pc_en;
	assign AluData1_en[2] = sraw || divw || remw;
	assign AluData1_en[1] = srliw || divuw || remuw;
	assign AluData1_en[0] = ~pc_en && ~sraw && ~srliw && ~( divw || remw || remuw || divuw);

	assign AluData2_en[6] = remuw || divuw;
	assign AluData2_en[5] = divw || remw;
	assign AluData2_en[4] = jump_en || op_jalr;
	assign AluData2_en[3] = imm_en && shiftimm_en;
	assign AluData2_en[2] = imm_en && ~shiftimm_en;
	assign AluData2_en[1] = ~imm_en && shiftimm_en;
	assign AluData2_en[0] = ~imm_en && ~shiftimm_en && ~(divw || remw || remuw || divuw);
	
	assign csr_wen[0] = csrrw;
	assign csr_wen[1] = csrrs;
endmodule
